/**
 * La classe GrapheValuee
 * @author Klelifa Sarah, Razavet Maël
 * @version 1.0
 */
package fr.eisti.ing1.projetgsiKlelifaRazavet.Graphe;

//imports nécessaires
import fr.eisti.ing1.projetgsiKlelifaRazavet.Objets.Personne;
import java.util.HashSet;
import java.util.Set;

public class GrapheValuee<T extends Comparable<T>> {
    //Déclaration des attributs
    private int nbSommet;
    private Set<AreteValuee<T>> ensembleArete;

    /**
     * constructeur initialisé
     * @param n le nombre de sommets
     */
    public GrapheValuee() {
        this.nbSommet = 0;
        this.ensembleArete = new HashSet<AreteValuee<T>>();
    }

   //methodes
   /**
    * Fonction qui permet d'evaluer un lien d'amitier
    * @param personne1 la personne voulant evalué le lien d'amitier
    * @param personne2 la personne etant evalué
    * @param evaluation
    */
    public void evaluer(Personne personne1, Personne personne2, int evaluation){
        for(AreteValuee<T> ar : ensembleArete){
                if(ar.getSommet1().equals(personne1) && ar.getSommet2().equals(personne2)){
                    ar.setEvaluation(evaluation);
                    System.out.println("Vous venez de donner une note a votre amitié "+evaluation);
                }
            }
    }

    /**
     * Fonction qui ajoute un ami a la liste des propositions d'une personne
     * @param personne1 ami proposant son ajout dans la liste
     * @param personne2 personne dont sa liste est modifié
     */
    public void proposerAmi(Personne personne1, Personne personne2){
        if(!existeLien(personne1, personne2)){
            personne2.getPropositionAmi().add(personne1);
             System.out.println("Vous venez de demander en amis "+personne2.toString());
        }else{
            System.err.println("Vous êtes déjà amis");
        }
    }

    /**
     * Fonction qui permet de vérifier si il existe un lien entre deux personnes
     * @param personne1
     * @param personne2
     * @return vrai si il existe un lien, faux sinon
     */
    public Boolean existeLien(Personne personne1, Personne personne2){
        Boolean lienExiste;
        lienExiste = false;
        //on parcourt toutes les aretes du graphe pour chercher un lien entre les deux personnes, si il existe on renvoit vrai
        for(AreteValuee<T> ar : ensembleArete){
                lienExiste= ((ar.getSommet1().equals(personne1) && ar.getSommet2().equals(personne2)) || ar.getSommet1().equals(personne2) || ar.getSommet2().equals(personne1))|| lienExiste;
        }
        return lienExiste;
    }

    /**
     * Fonction qui permet de refuser un ami proposé
     * @param personne1 personne refusant l'ami
     * @param personne2 personne s'etant proposé
     */
    public void refuserAmiProposer(Personne personne1, Personne personne2){
         //si la liste de proposition d'ami contient la personne que l'on veut ajouter
        if(personne1.getPropositionAmi().contains(personne2)){
            //on la suprprime de la liste de proposition
            personne1.getPropositionAmi().remove(personne2);
            System.out.println(" Vous venez de refuser en amis "+personne2.toString());
        }
    }

    /**
     * Fonction qui permet d'accepter un ami proposer
     * @param personne1 personne acceptant l'ami
     * @param personne2 personne s'etant proposé
     */
    public void accepterAmi(Personne personne1, Personne personne2){
        Boolean personne1EstDejaDansGraphe;
        Boolean personne2EstDejaDansGraphe;

        personne1EstDejaDansGraphe = false;
        personne2EstDejaDansGraphe = false;

        //si la liste de proposition d'ami contient la personne que l'on veut ajouter
        if(personne1.getPropositionAmi().contains(personne2)){
            //on la suprprime de la liste de proposition et on ajoute un lien entre les deux personnes
            personne1.getPropositionAmi().remove(personne2);
            //on regarde qui est deja dans la graphe afin de savoir combien de sommet on ajoute
             for(AreteValuee<T> ar : ensembleArete){
                personne1EstDejaDansGraphe = (ar.getSommet1().equals(personne1) || ar.getSommet2().equals(personne1)) || personne1EstDejaDansGraphe;
                personne2EstDejaDansGraphe = (ar.getSommet1().equals(personne2) || ar.getSommet2().equals(personne1)) || personne2EstDejaDansGraphe;
             }
             this.ensembleArete.add(new AreteValuee<T>(personne1,personne2));
             this.ensembleArete.add(new AreteValuee<T>(personne2,personne1));
             //si aucune des deux personne est dans le graphe on ajoute 2 sommets
             if(!personne1EstDejaDansGraphe){
                 this.nbSommet++;
             }
             if(!personne2EstDejaDansGraphe){
                 this.nbSommet++;
             }
             System.out.println(personne1.toString()+" viens d'accepter la demande d'ajout d'amis "+personne2.toString());
        }
    }
    

    /**
     * Fonction qui permet de supprimer un ami de sa liste d'ami
     * @param personne1
     * @param personne2
     */
    public void supprimerAmi(Personne personne1, Personne personne2){
            //on parcourt l'ensemble des aretes du graphe et si on trouve l'ami correspondant on le supprime
            for(AreteValuee<T> ar : ensembleArete){
                if((ar.getSommet1().equals(personne1) && ar.getSommet2().equals(personne2)) || ar.getSommet1().equals(personne2) || ar.getSommet2().equals(personne1)){
                    this.ensembleArete.remove(ar);
                    System.out.println("Vous venez de supprimer "+personne2.toString());
                }
            }
    }

   
    /**
     * représentation textuelle du graphe
     * @return la représentation textuelle
     */
    @Override
    public String toString() {
        //déclaration et initialisation des variables
        String res = "";
        //on parcours l'ensemble d'arete du graphe
        for (AreteValuee<T> ar : this.ensembleArete) {
            //on stocke dans res les représentations textuelles des aretes du graphe
            res = res + " " + ar.toString() + "\n";
        }
        //on retourne res
        return res;
    }
}
